import Icon from '@/components/Icon'
import style from '@/pages/CarList/index.module.scss'
//引入图片
import bannerImg from '@/assets/images/banner.png'
import goBackWhiteImg from '@/assets/images/goBackWhite.jpg'
import goBackBlueImg from '@/assets/images/goBackBlue.png'
import changeListBlueImg from '@/assets/images/changeListBlue.png'
import changeListBlueSmallImg from '@/assets/images/changeListBlueSmall.png'
import changeListWhiteSmallImg from '@/assets/images/changeListWhiteSmall.png'
import screeningArrowImg from '@/assets/images/screeningArrow.png'
import prestrainImg from '@/assets/images/prestrain.png'
import loadMoreImg from '@/assets/images/loadMore.gif'
import changeListWhiteImg from '@/assets/images/changeListWhite.png'
import likeBox from '@/assets/images/like-box.png'
import goBack from '@/assets/images/goback.gif'
import filtrateImg from '@/assets/images/filtrate.png'
// 下部列表项
import CarItem from '@/pages/CarList/components/CarItem'
import { PullToRefresh } from 'antd-mobile'
//下部列表小图
import CarItemSmall from '@/pages/CarList/components/CarItemSmall'
import { useEffect, useRef, useState } from 'react'
import { http } from '@/utils/http'
import Particulars from '@/pages/CarList/components/Particulars'
//引入汽车类型
import { carListType } from '@/types/data'
import { carDataType } from '@/types/data'
//引入查询动画
import { getKeyframes } from '@/utils/searchAnimate'

const CarrList = () => {
  // const sub = useRef<HTMLDivElement>(null)
  //切换列表状态，true为大图，false为小图
  const [listState, setListState] = useState(false)
  //存放汽车数据的状态
  const [carData, setCarData] = useState<carListType>([])
  //控制进入详情页,true为进入，false为不进入
  const changeGoParticulars = (bool: boolean) => {
    setGoParticulars(bool)
  }
  const [goParticulars, setGoParticulars] = useState(false)
  //组件一挂载就请求数据的方法+预加载
  const getCarList = async (page = 1) => {
    const res = (await http.post('/api/getCarList', { page })) as carListType
    // Promise.all(
    //   res.map((e) => {
    //     return new Promise((resolve, reject) => {
    //       let image = new Image()
    //       image.src = `http://www.ibugthree.com/${e.img_src}`
    //       image.onload = (e) => {
    //         console.log('图片预加载完成一张')
    //         resolve('')
    //       }
    //     })
    //   })
    // ).then(
    //   (e) => {
    //     console.log('成功')
    //     setCarData(res)
    //     setPrestrain(false)
    //   },
    //   (e) => {
    //     console.log('失败')
    //     setCarData(res)
    //     setPrestrain(false)
    //   }
    // )
    //不预加载
    setCarData(res)
    setPrestrain(false)
  }
  //是否预加载
  const [prestrain, setPrestrain] = useState(true)
  //组件一挂载就预加载而且展示loading，预加载完成更新组件
  useEffect(() => {
    getCarList()
  }, [])
  //放置当前点击的数据
  const [pitchOn, setPitOn] = useState<carDataType>()
  //传递给下级组件该状态的方法
  const goSetPitOn = (data: carDataType) => {
    setPitOn(data)
  }
  //上滑加载的ref和总盒子的ref
  const upload = useRef<HTMLDivElement>(null)
  const carList = useRef<HTMLDivElement>(null)
  //控制加载请求数据的状态
  const [uploadState, setUploadState] = useState(false)
  //触发上滑加载更新数据的逻辑
  const uploadGetData = async (page: number) => {
    setUploadState(true)
    const res = (await http.post('/api/getCarList', { page })) as carListType
    setCarData([...carData, ...res])
    setUploadState(false)
    setPage(page + 1)
  }
  //设置记录上滑加载滑动位置的值以及节流阀
  const supportRef = useRef<HTMLDivElement | null>(null) //托底盒子的dom句柄
  const [flag, setFlag] = useState(true) //控制触底开始的节流阀
  const [uploadScroll, setUploadScroll] = useState(0) //触底滚动位置初始值
  const [uploadScrollEnd, setUploadScrollEnd] = useState(0) //触底滚动位置结束值
  //头部导航区判定是否滚动来切换黑白样式
  const [navClass, setNavClass] = useState(true)
  //计算头部导航滚动的时候的透明度变化
  const scrollHeight = carList.current?.scrollTop //页面滚动高度
  const [transparentInterval, setTransparentInterval] = useState(0) //导航区透明依赖高度变化最大值
  const [navLucency, setNavLucency] = useState(0) //导航区透明度变化区间
  const screeningSubRef = useRef<HTMLDivElement | null>(null) //筛选区的dom句柄
  const navigationRef = useRef<HTMLDivElement | null>(null) //导航区的dom句柄
  //筛选区的定位逻辑
  const screeningSubToTopRef = useRef(0)
  useEffect(() => {
    screeningSubToTopRef.current = screeningSubRef.current!.offsetTop - navigationRef.current!.offsetHeight
  }, [])
  const [screeningSubPosition, setScreeningSubPosition] = useState(false) //筛选区盒子吸顶显示依据
  //记录页数
  const [page, setPage] = useState(1)
  //贝塞尔小球逻辑
  const wraperRef = useRef<HTMLDivElement | null>(null)

  const wraperAnimate = async (top: number, left: number, height: number, img_src: string, id: number, bool: boolean) => {
    console.log(bool)

    if (!bool) {
      changeCollectionRecords(id, bool)
      return
    }
    ;(wraperRef.current!.childNodes[0] as HTMLDivElement).style.backgroundImage = `url(http://www.ibugthree.com/${img_src})`
    //列表item组件点击红心的时候触发的逻辑
    //利用promise使异步操作同步化
    new Promise((resolve, reject) => {
      //搜索一阶动画动态改值，此步操作完成小球由小变大再变小的过程

      try {
        let animateName = getKeyframes('move') //通过封装的函数来获取名字为slide的keyframes函数
        animateName?.styleSheet.deleteRule(animateName!.index) //通过index删除之前的keyframes函数
        let insertKeyframes =
          '@keyframes move {' +
          '  0% {' +
          '    left: ' +
          (left + 30) +
          'px;' +
          '    top: ' +
          (top + height / 2 - 10) +
          'px;' +
          '    width: 30px;' +
          '    height: 30px;' +
          '    animation-duration: 1s;' +
          '  }' +
          '  50% {' +
          '    left: ' +
          (left + 110) +
          'px;' +
          '    top: ' +
          (top + height / 2 - 60) +
          'px;' +
          '    width: 50px;' +
          '    height: 50px;' +
          '    animation-duration: 1s;' +
          '  }' +
          '  100% {' +
          '    left: ' +
          (left + 110) +
          'px;' +
          '    top: ' +
          (top + height / 2 - 60) +
          'px;' +
          '    width: 25px;' +
          '    height: 25px;' +
          '    animation-duration: 1s;' +
          '  }' +
          '}'
        animateName?.styleSheet.insertRule(insertKeyframes, animateName?.index) //将修改后的函数和index添加进样式表
      } catch (error) {}
      //搜索改变完move动画之后将iniAnimate赋值给这个dom，随后执行一阶动画,并且显示小球
      wraperRef.current!.style.display = 'block'
      ;(wraperRef.current!.childNodes[0] as HTMLDivElement).className = 'iniAnimate'
      //由于一阶动画执行时机为3秒，那么就在三秒之后改变这个元素的位置为需要跳往下方的位置，随后在计时结束时改变promise状态为成功，随即触发then指定的成功回调
      setTimeout(() => {
        ;(wraperRef.current! as HTMLDivElement).className = 'wraper'
        ;(wraperRef.current!.childNodes[0] as HTMLDivElement).style.left = left + 110 + 'px'
        ;(wraperRef.current!.childNodes[0] as HTMLDivElement).style.top = top + height / 2 - 60 + 'px'
        resolve('')
      }, 3000)
    }).then((e) => {
      console.log('asd')

      //动态计算需要跳跃的高度
      let ww = 480 - top + 70 + 100

      // let ww = 450 - top + height / 2 + 20
      //动态更改贝塞动画的值并且设置动画，为了增加程序健壮性，进行捕错。保证程序可以正常运行。
      try {
        let animateName = getKeyframes('ver-animation') //通过封装的函数来获取名字为slide的keyframes函数
        animateName?.styleSheet.deleteRule(animateName!.index) //通过index删除之前的keyframes函数
        let insertKeyframes =
          '@keyframes ver-animation{\n' +
          '            0%{\n' +
          '                z-index: 999;\n' +
          '                top: ' +
          0 +
          'px;\n' +
          '            }\n' +
          '            100%{\n' +
          '                z-index: 999;\n' +
          '                top: ' +
          ww +
          'px;\n' +
          '            }\n' +
          '        }'
        animateName?.styleSheet.insertRule(insertKeyframes, animateName?.index) //将修改后的函数和index添加进样式表
        ;(wraperRef.current!.childNodes[0] as HTMLDivElement).className = 'item'
      } catch (error) {}
      //点击之后一秒钟之后初始化小球
      setTimeout(() => {
        //小球做完运动完成后更新收藏列表中的id，页面中的小虹心数量就会同步更改
        changeCollectionRecords(id, bool)
        wraperRef.current!.style.display = 'none'
        wraperRef.current!.className = ''
        ;(wraperRef.current!.childNodes[0] as HTMLDivElement).style.left = 0 + 'px'
        ;(wraperRef.current!.childNodes[0] as HTMLDivElement).style.top = 0 + 'px'
        ;(wraperRef.current!.childNodes[0] as HTMLDivElement).className = ''
      }, 1000)
    })
  }
  //点赞收藏记录数量的逻辑
  const [collectionRecords, setCollectionRecords] = useState<number[]>([]) //保存收藏记录的状态
  const changeCollectionRecords = (id: number, bool: boolean) => {
    console.log(bool)

    //改变收藏记录的方法，判断依据为查看collectionRecords中有无之前收藏保存的id，和下级item项传递过来是否收藏布尔值来判断是收藏还是取消收藏
    if (bool) {
      //增加逻辑
      setCollectionRecords([...collectionRecords, id])
    } else {
      //删除逻辑
      let newCollectionRecords = collectionRecords.filter((e) => {
        return e !== id
      })
      setCollectionRecords(newCollectionRecords)
    }
  }

  //回顶部逻辑
  const [goTop, setGoTop] = useState<number | undefined>(0)
  //判断返顶的滑动距离
  const [goTopStartFlag, setGoTopStartFlag] = useState(true) //返顶开始开闭阀
  const [goTopStart, setGoTopStart] = useState(0) //返顶开始
  const [goTopEnd, setGoTopEnd] = useState(0) //返顶结束
  //
  //carList滚动事件
  const carListScroll = (e: React.UIEvent<HTMLDivElement, UIEvent>) => {
    //上滑加载逻辑
    let height = (carList.current?.childNodes[0] as HTMLDivElement).offsetHeight
    let clientHeight = carList.current!.clientHeight
    let scrollHeight = carList.current!.scrollTop
    if (height - scrollHeight < clientHeight + 5) {
      if (uploadState) return
      uploadGetData(page)
    }
    //判断筛选区吸顶逻辑
    setTransparentInterval(screeningSubRef.current!.offsetTop - navigationRef.current!.offsetHeight) //吸顶和透明度变化最大区间
    if (scrollHeight > 1) {
      //设置导航区滚动还是顶部的样式
      setNavClass(false)
      //设置导航区透明度
      setNavLucency(scrollHeight / transparentInterval)
    } else {
      //设置导航区滚动还是顶部的样式
      setNavClass(true)
    }
    //筛选区变化的逻辑，高度大于一定值改状态为true转固定定位
    if (scrollHeight > screeningSubToTopRef.current) {
      setScreeningSubPosition(true)
    } else {
      setScreeningSubPosition(false)
    }
  }
  //carList触摸事件
  const carListTouchStart = (e: React.TouchEvent<HTMLDivElement>) => {
    setGoTop(scrollHeight)
  }
  //carList滑动事件
  const carListTouchMove = (e: React.TouchEvent<HTMLDivElement>) => {
    //上划加载逻辑
    let height = (carList.current?.childNodes[0] as HTMLDivElement).offsetHeight
    let clientHeight = carList.current!.clientHeight
    let scrollHeight = carList.current!.scrollTop
    if (height - scrollHeight < clientHeight + 1) {
      if (flag) {
        setFlag(false)
        setUploadScroll(e.changedTouches[0].pageY)
      }
      setUploadScrollEnd(e.changedTouches[0].pageY)
    }
    //返回顶部逻辑,判断上划还是下划的逻辑
    if (scrollHeight < 500) {
      setGoTopStart(0)
      setGoTopEnd(0)
    } else {
      if (scrollHeight >= goTop! + 1) {
        setGoTop(scrollHeight)
        setGoTopStartFlag(true)
        setGoTopStart(0)
      } else {
        setGoTop(scrollHeight)
        if (goTopStartFlag) {
          setGoTopStartFlag(false)
          setGoTopStart(scrollHeight)
        }
        setGoTopEnd(scrollHeight)
      }
    }
  }
  //carList手指抬起事件
  const carListTouchEnd = async (e: React.TouchEvent<HTMLDivElement>) => {
    //上滑加载逻辑
    if (!flag) {
      setFlag(true)
      setUploadScroll(0)
      setUploadScrollEnd(0)
    }
  }
  return (
    <PullToRefresh
      onRefresh={async () => {
        getCarList((Math.random() * 10) | 0)
      }}
    >
      <div
        ref={carList}
        className={style.root}
        onScroll={carListScroll}
        onTouchStart={carListTouchStart}
        onTouchMove={carListTouchMove}
        onTouchEnd={carListTouchEnd}
      >
        {console.log(collectionRecords)}
        <div className='sub'>
          {/* 返顶 */}
          <div
            className={goTopStart - goTopEnd > 50 ? 'goBack goBackYes' : 'goBack'}
            onTouchStart={(e) => {
              carList.current!.scrollTop = 0
            }}
          >
            <img src={goBack} alt='' />
          </div>
          {/* 收藏的老心 */}
          <div className={goTopStart - goTopEnd > 50 ? 'likeBox likeBoxYes' : 'likeBox'}>
            <img src={likeBox} alt='' />
            <div className='collectNumber'>{collectionRecords.length}</div>
          </div>
          {/* 贝塞尔老球 */}
          <div ref={wraperRef} className={''}>
            <div className=''></div>
          </div>
          {/* 首页导航，返回与切换列表 */}
          <div
            className='navigation'
            style={{
              opacity: scrollHeight! < 1 ? 1 : navLucency,
              backgroundColor: scrollHeight! > 1 ? '#fff' : '',
              position: scrollHeight !== 0 ? 'fixed' : undefined,
            }}
            ref={navigationRef}
          >
            {navClass ? (
              <img src={goBackBlueImg} alt='' className='blue-go-back' />
            ) : (
              <img src={goBackWhiteImg} alt='' className='blue-go-back' />
            )}
            {navClass ? <div></div> : <div className='title'>全自营 更放心</div>}
            {navClass ? (
              listState ? (
                <img
                  src={changeListBlueSmallImg}
                  alt=''
                  className='change'
                  onTouchStart={(e) => {
                    setListState(!listState)
                  }}
                />
              ) : (
                <img
                  src={changeListBlueImg}
                  alt=''
                  className='change'
                  onTouchStart={(e) => {
                    setListState(!listState)
                  }}
                />
              )
            ) : listState ? (
              <img
                src={changeListWhiteSmallImg}
                alt=''
                className='change'
                onTouchStart={(e) => {
                  setListState(!listState)
                }}
              />
            ) : (
              <img
                src={changeListWhiteImg}
                alt=''
                className='change'
                onTouchStart={(e) => {
                  setListState(!listState)
                }}
              />
            )}
          </div>
          {/* 页首图片 */}
          <img src={bannerImg} className='page-heading-img' alt='' />
          {/* 筛选区 */}
          <div className='screeningSub' style={{ display: screeningSubPosition ? 'block' : 'none' }}></div>
          <div
            className='screeningSub'
            style={{
              position: screeningSubPosition ? 'fixed' : undefined,
              top: screeningSubPosition ? navigationRef.current!.offsetHeight : 0,
              backgroundColor: screeningSubPosition ? '#fff' : '#848fab',
              zIndex: screeningSubPosition ? '50' : '',
            }}
            ref={screeningSubRef}
          >
            {listState ? (
              <div className='screening'>
                <div className='screening-item'>
                  <span>综合排序</span>
                  <Icon type='icon-jiantou_shangxiaqiehuan'></Icon>
                </div>
                <div className='screening-item'>
                  <span>品牌</span>
                  <Icon type='icon-xiajiantou'></Icon>
                </div>
                <div className='screening-item'>
                  <span>价格</span>
                  <Icon type='icon-xiajiantou'></Icon>
                </div>
                <div className='screening-item'>
                  <span>筛选</span>
                  <Icon type='icon-shaixuan1'></Icon>
                </div>
              </div>
            ) : (
              <div className='screening'>
                <div className='screening-small-item'>
                  <div>综合排序</div>
                  <img src={screeningArrowImg} alt='' className='screen' />
                </div>
                <div className='screening-small-item'>
                  <div>筛选</div>
                  <img src={filtrateImg} alt='' className='screen' />
                </div>
              </div>
            )}
          </div>
          {/* 首屏预加载展示的转圈图 */}
          {prestrain ? (
            <div className='prestrain'>
              <img style={{ animation: prestrain ? 'turn 1s linear infinite' : '' }} src={prestrainImg} alt='' />
            </div>
          ) : (
            <div className='car-list'>
              {listState
                ? carData?.map((e) => {
                    return (
                      <CarItem goSetPitOn={goSetPitOn} carDataType={e} changeGoParticulars={changeGoParticulars}></CarItem>
                    )
                  })
                : carData?.map((e) => {
                    return (
                      <CarItemSmall
                        goSetPitOn={goSetPitOn}
                        changeGoParticulars={changeGoParticulars}
                        carDataType={e}
                        wraperAnimate={wraperAnimate}
                        changeCollectionRecords={changeCollectionRecords}
                      ></CarItemSmall>
                    )
                  })}
            </div>
          )}
          {/* 托底透明盒子 */}
          <div
            className='support'
            ref={supportRef}
            style={{ height: 50 + uploadScroll - uploadScrollEnd, transition: flag ? '.3s' : 'none' }}
          ></div>
          {/* 上滑加载 */}
          <div className='Upload' style={{ display: prestrain ? 'none' : 'block' }} ref={upload}>
            <img src={loadMoreImg} alt='' />
            上划加载
          </div>
        </div>
        {/* 侧边组件滑动显示 */}
        <Particulars
          pitchOn={pitchOn}
          changeGoParticulars={changeGoParticulars}
          left={goParticulars ? '0' : '100vw'}
        ></Particulars>
      </div>
    </PullToRefresh>
  )
}
export default CarrList
